//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

namespace Microsoft.Research.ScientificWorkflow.TridentModel
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Text.RegularExpressions;
    using Microsoft.Research.DataLayer;
    using System.Globalization;

    /// <summary>
    /// 
    /// </summary>
    public class WebServiceWizardModel : INotifyPropertyChanged
    {
        public const string ActivityNamespace = "Microsoft.Research.eResearch.TridentActivity";

        #region Private Variables

        private ObservableCollection<string> availableWebMethods = new ObservableCollection<string>();

        private Collection<Category> categoryList = new Collection<Category>();

        private static string proxyAssembly;

        private Dictionary<string, Type> activityTypes = new Dictionary<string, Type>();

        private string selectedWebMethod;

        private ObservableCollection<WebMethodParameterInfo> selectedWebMethodParamList = new ObservableCollection<WebMethodParameterInfo>();

        private string activityName;

        private static string activityAssembly;

        private string activityImageSource;

        private string activityDescription;

        private string activityCategory;

        private bool isCopyActivityCodeEnabled;

        private string outputBinariesPath;

        private static string tempPath;

        private Category selectedCategory;

        private bool isImportSuccessful;

        private bool isActivityGeneratedSuccessful;

        private Uri webServiceURL;

        #endregion

        #region Wizard Properties

        public Uri WebServiceUrl
        {
            get { return webServiceURL; }
            set
            {
                webServiceURL = value;
                this.OnNotifyPropertyChanged("WebServiceURL");
            }
        }

        public Category SelectedCategory
        {
            get { return selectedCategory; }
            set
            {
                selectedCategory = value;
                this.OnNotifyPropertyChanged("SelectedCategory");
            }
        }

        private Dictionary<string, ObservableCollection<WebMethodParameterInfo>> parameterInfo =
            new Dictionary<string, ObservableCollection<WebMethodParameterInfo>>();

        public ObservableCollection<string> AvailableWebMethods
        {
            get { return availableWebMethods; }
            set { availableWebMethods = value; }
        }

        public Collection<Category> CategoryList
        {
            get
            {
                return categoryList;
            }
            set
            {
                categoryList = value;
            }
        }

        public static string TempPath
        {
            get { return tempPath; }
            set { tempPath = value; }
        }

        public static string ProxyTempPath
        {
            get { return proxyAssembly; }
            set { proxyAssembly = value; }
        }

        public Dictionary<string, Type> ActivityTypes
        {
            get { return activityTypes; }
            set { activityTypes = value; }
        }

        public Dictionary<string, ObservableCollection<WebMethodParameterInfo>> ParameterInfo
        {
            get { return parameterInfo; }
            set { parameterInfo = value; }
        }

        public bool IsImportSuccessful
        {
            get { return isImportSuccessful; }
            set
            {
                isImportSuccessful = value;
                this.OnNotifyPropertyChanged("IsImportSuccessful");
            }
        }

        public bool IsActivityGeneratedSuccessful
        {
            get { return isActivityGeneratedSuccessful; }
            set
            {
                isActivityGeneratedSuccessful = value;
                this.OnNotifyPropertyChanged("IsActivityGeneratedSuccessful");
            }
        }

        #endregion

        #region Activity Properties

        public string SelectedWebMethod
        {
            get
            {
                return selectedWebMethod;
            }
            set
            {
                selectedWebMethod = value;
                if (!string.IsNullOrEmpty(SelectedWebMethod))
                    ActivityName = SelectedWebMethod;

                if (!string.IsNullOrEmpty(selectedWebMethod))
                    SelectedWebMethodParamList = ParameterInfo[selectedWebMethod];

                this.OnNotifyPropertyChanged("SelectedWebMethod");
            }
        }

        public ObservableCollection<WebMethodParameterInfo> SelectedWebMethodParamList
        {
            get
            {
                return selectedWebMethodParamList;
            }
            set
            {
                selectedWebMethodParamList = value;
                this.OnNotifyPropertyChanged("SelectedWebMethodParamList");
            }
        }

        public string ActivityName
        {
            get
            {
                return activityName;
            }
            set
            {
                activityName = value.Trim();
                this.OnNotifyPropertyChanged("ActivityGivenName");
            }
        }

        public static string ActivityTempPath
        {
            get { return activityAssembly; }
            set { activityAssembly = value; }
        }

        public string ActivityImageSource
        {
            get
            {
                return activityImageSource;
            }
            set
            {
                activityImageSource = value;
                this.OnNotifyPropertyChanged("ActivityImageSource");
            }
        }

        public string ActivityDescription
        {
            get
            {
                return activityDescription;
            }
            set
            {
                activityDescription = value;
                this.OnNotifyPropertyChanged("ActivityDescription");
            }
        }

        public string ActivityCategory
        {
            get { return activityCategory; }
            set { activityCategory = value; }
        }

        public bool IsCopyActivityCodeEnabled
        {
            get
            {
                return isCopyActivityCodeEnabled;
            }
            set
            {
                isCopyActivityCodeEnabled = value;
                this.OnNotifyPropertyChanged("IsCopyActivityCodeEnabled");
            }
        }

        public string OutputBinariesPath
        {
            get
            {
                return outputBinariesPath;
            }
            set
            {
                outputBinariesPath = value;
                this.OnNotifyPropertyChanged("OutputBinariesPath");
            }
        }

        #endregion

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Fires the property changed event.
        /// </summary>
        /// <param name="propertyName">Name of the property which has been modified.</param>
        private void OnNotifyPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion
    }

    /// <summary>
    /// 
    /// </summary>
    public class WebMethodParameterInfo
    {
        #region Private Variables
        private Regex removeSpaceRegex = new Regex(@"\s+");

        private string webMethodName;

        private string webMethodParamName;

        private string activityParamName;

        private string activityParamValidName;

        private string paramType;

        private string isRequired;

        private ParameterDirection paramDirection;

        private bool isBuitIn;
        private object defaultValue;

        #endregion

        #region Parameter Info Properties
        public object DefaultValue
        {
            get { return defaultValue; }
            set { defaultValue = value; }
        }
        public bool IsBuiltIn
        {
            get { return isBuitIn; }
            set { isBuitIn = value; }
        }
        public string WebMethodName
        {
            get { return webMethodName; }
            set { webMethodName = value; }
        }

        public string WebMethodParamName
        {
            get { return webMethodParamName; }
            set { webMethodParamName = value; }
        }

        public string ActivityParamName
        {
            get { return activityParamName; }
            set { activityParamName = value; }
        }

        public string ActivityParamValidName
        {
            get
            {
                if (!string.IsNullOrEmpty(activityParamName))
                {
                    activityParamValidName =
                        removeSpaceRegex.Replace("Get_" + ActivityParamName, @"");
                }

                return activityParamValidName;
            }
        }

        public ParameterDirection ParamDirection
        {
            get { return paramDirection; }
            set { paramDirection = value; }
        }

        public string ParamType
        {
            get { return paramType; }
            set { paramType = value; }
        }

        public string IsRequired
        {
            get { return isRequired; }
            set { isRequired = value; }
        }

        #endregion

        public override string ToString()
        {
            if (this.WebMethodParamName != null)
            {
                return string.Format(CultureInfo.InvariantCulture, "WebMethodParamName: {0}", this.WebMethodParamName);
            }
            return base.ToString();
        }
    }

    public enum ParameterDirection
    {
        In,
        Out,
    }

    /// <summary>
    /// Class to create category tree.
    /// </summary>
    public class Category
    {
        public Category()
        {
            Children = new Collection<Category>();
        }

        public Category Parent { get; set; }
        public string Name { get; set; }
        public Collection<Category> Children { get; set; }

        public bool IsSelected { get; set; }

        public override string ToString()
        {
            if (!string.IsNullOrEmpty(this.Name))
            {
                return this.Name;
            }
            return base.ToString();
        }
    }
}
